package br.uefs.dexa.rfframework.strategies.lire;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Random;

import br.uefs.dexa.rfframework.gui.GUIActionListener;
import br.unicamp.ic.lis.rfframework.RFEngine;
import br.unicamp.ic.lis.rfframework.impl.interfaces.ICollectionInitializationStrategy;
import br.unicamp.ic.lis.rfframework.impl.interfaces.ICollectionOrganizationStrategy;
import br.unicamp.ic.lis.rfframework.impl.interfaces.IInitialSetOfObjectsRetrievalStrategy;
import br.unicamp.ic.lis.rfframework.impl.interfaces.IUserActionListener;
import br.unicamp.ic.lis.rfframework.objects.DigitalObject;
import br.unicamp.ic.lis.rfframework.objects.DigitalObjectSet;
import br.unicamp.ic.lis.rfframework.objects.LabeledDigitalObject;

public class TestLireRFEngine extends RFEngine {

public static final int NUMBER_OF_OBJECTS_SHOWN = 20;
	
	IUserActionListener actionListener = new GUIActionListener();
	ICollectionInitializationStrategy collectionInitializer = new LireCollectionInitializer();
	IInitialSetOfObjectsRetrievalStrategy initialRetriever = new LireInitialSetRetriever();
	ICollectionOrganizationStrategy collectionOrganizer = new LireCollectionOrganizer();
	
	List<DigitalObject> list = new ArrayList<DigitalObject>();
	
	public TestLireRFEngine()
	{
		for (int i = 16010; i < 20000; i++) {
			DigitalObject object = new DigitalObject((long) i);
			list.add(object);
		}
	}
	
	
	@Override
	protected DigitalObjectSet<DigitalObject> initializeCollection() {
		//return ramdomize(list, false);
		return collectionInitializer.run();
		
	}

	@Override
	protected DigitalObjectSet<LabeledDigitalObject> userIndicationOfQueryPattern(
			DigitalObjectSet<DigitalObject> collection) {
		
		return actionListener.indicationOfQueryPattern(collection);
	}

	@Override
	protected DigitalObjectSet<LabeledDigitalObject> userIndicationOfObjectsRelevance(
			DigitalObjectSet<DigitalObject> retrievedObjects,
			DigitalObjectSet<LabeledDigitalObject> queryPattern) {
		
		return actionListener.userIndicationOfObjectsRelevance(retrievedObjects, queryPattern);
	}

	@Override
	protected DigitalObjectSet<DigitalObject> computeInitialSetOfObjects(
			DigitalObjectSet<DigitalObject> collection,
			DigitalObjectSet<LabeledDigitalObject> queryPattern) {
		
		//return ramdomize(list, true);
		return initialRetriever.run(collection, queryPattern);
	}

	@Override
	protected DigitalObjectSet<LabeledDigitalObject> updateQueryPattern(
			DigitalObjectSet<LabeledDigitalObject> queryPattern,
			DigitalObjectSet<LabeledDigitalObject> labeledObjects) {
		
		return queryPattern;
	}

	@Override
	protected DigitalObjectSet<DigitalObject> organizeCollection(
			DigitalObjectSet<DigitalObject> collection,
			DigitalObjectSet<LabeledDigitalObject> queryPattern,
			DigitalObjectSet<LabeledDigitalObject> labeledObjects) {
		
//		for (int i = 0; i < 100000; i++) {
//			System.out.println("i: " + i);
//		}
		
		//return ramdomize(list, true);
		
		return collectionOrganizer.run(collection, queryPattern, labeledObjects);
	}

	@Override
	protected DigitalObjectSet<DigitalObject> selectObjectsToReturn(
			DigitalObjectSet<DigitalObject> collection,
			DigitalObjectSet<LabeledDigitalObject> queryPattern) {
		
		//return ramdomize(list, true);
		return collection;
	}

	@Override
	protected boolean showSetOfObjects(
			DigitalObjectSet<DigitalObject> retrievedObjects) {
		
		return actionListener.showSetOfObjects(retrievedObjects);
	}
	
	private static DigitalObjectSet<DigitalObject> ramdomize(List<DigitalObject> list, boolean limitNumberOfObjects)
	{
		DigitalObjectSet<DigitalObject> collection = new DigitalObjectSet<DigitalObject>();
		long seed = System.nanoTime();
		Collections.shuffle(list, new Random(seed));
		int numberOfObjects;
		
		if(limitNumberOfObjects)
			numberOfObjects = NUMBER_OF_OBJECTS_SHOWN;
		else
			numberOfObjects = list.size();
		
		for (int i = 0; i < numberOfObjects; i++) {
			collection.addObject(new DigitalObject(list.get(i).getId()));
		}
		
		return collection;
	}
	
//	public static void main(String[] args) 
//	{
//		TesteLireRFEngine rf = new TesteLireRFEngine();
//		rf.run();
//	}

}
